﻿using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rosetta.AddIns.Compression;
using Rosetta.Composition;
using Rosetta.Default;
using Rosetta.Default.AddIns;

namespace Rosetta.Tests
{
    [TestClass]
    public class IconRipperTests
    {
        [TestMethod]
        public void TestIconRipper()
        {
            var container = new Container();

            // Load Add-Ins
            container.LoadAssembly(typeof(RangeConverter).Assembly);
            container.LoadAssembly(typeof(ZipFileConverter).Assembly);

            // Build IconRipper template
            var template = new Template(container);

            // Add-Ins
            const string stringInputter = "Rosetta.Default.AddIns.Text.StringInputter, Rosetta.Default";
            const string regexInputter = "Rosetta.Default.AddIns.RegularExpressions.RegexInputter, Rosetta.Default";
            const string directoryInputter = "Rosetta.Default.AddIns.IO.DirectoryInputter, Rosetta.Default";

            const string rangeConverter = "Rosetta.Default.AddIns.RangeConverter, Rosetta.Default";
            const string typeConverter = "Rosetta.Default.AddIns.TypeConverter, Rosetta.Default";
            const string stringConverter = "Rosetta.Default.AddIns.Text.StringConverter, Rosetta.Default";
            const string webAddressConverter = "Rosetta.Default.AddIns.Net.WebAddressConverter, Rosetta.Default";
            const string downloader = "Rosetta.Default.AddIns.Net.Downloader, Rosetta.Default";
            const string regexConverter = "Rosetta.Default.AddIns.RegularExpressions.RegexConverter, Rosetta.Default";
            const string zipFileConverter = "Rosetta.AddIns.Compression.ZipFileConverter, Rosetta.AddIns.Compression";

            const string zipEntryOutputter = "Rosetta.AddIns.Compression.ZipEntryOutputter, Rosetta.AddIns.Compression";

            /////////////////
            // Add inputs: //
            /////////////////
            var baseUriInputNode = template.AddInputNode(stringInputter, "GetString");
            baseUriInputNode.Description = "baseUri";
            baseUriInputNode.Context = "http://iconfactory.com/freeware/icon?page=";

            var downloadRegexInputNode = template.AddInputNode(regexInputter, "CreateCompiled");
            downloadRegexInputNode.Description = "downloadRegex";
            downloadRegexInputNode.Context = "/assets/freeware/.*?/download.zip";

            var pageStartInputNode = template.AddInputNode(stringInputter, "GetInt32");
            pageStartInputNode.Description = "pageStart";
            pageStartInputNode.Context = "1";

            var pageCountInputNode = template.AddInputNode(stringInputter, "GetInt32");
            pageCountInputNode.Description = "pageCount";
            pageCountInputNode.Context = "1";

            var filterRegexInputNode = template.AddInputNode(regexInputter, "CreateCompiled");
            filterRegexInputNode.Description = "filterRegex";
            filterRegexInputNode.Context = ".*\\.ico$";

            var outputDirectoryInputNode = template.AddInputNode(directoryInputter, "GetDirectory");
            outputDirectoryInputNode.Description = "outputDirectory";
            outputDirectoryInputNode.Context = new DirectoryInfo(@"G:\Documents and Settings\Steve\My Documents\Pictures\Icons2\");

            /////////////////////
            // Add converters: //
            /////////////////////
            var pagesRangeConverterNode = pageStartInputNode.AddChild(rangeConverter, "GetInt32Range", 0).EndPoint;
            pagesRangeConverterNode.Description = "pagesRange";
            pageCountInputNode.AddChild(pagesRangeConverterNode, 1);
            // Created range (1->2)

            var pageNumberConverterNode = pagesRangeConverterNode.AddChild(typeConverter, "Int32ToString", 0).EndPoint;
            // Converted current index to string ("1", "2")

            var pageUriConverterNode = baseUriInputNode.AddChild(stringConverter, "ConcatTwo", 0).EndPoint;
            pageUriConverterNode.Description = "pageUri";
            pageNumberConverterNode.AddChild(pageUriConverterNode, 1);

            var pageAddressConverterNode = pageUriConverterNode.AddChild(webAddressConverter, "FromString", 0).EndPoint;
            pageAddressConverterNode.Description = "pageAddress";
            // Created webAddresses ("http://iconfactory.com/freeware/icon?page=1")

            var pageDownloaderConverterNode = pageAddressConverterNode.AddChild(downloader, "GetString", 0).EndPoint;
            pageDownloaderConverterNode.Description = "pageDownloader";

            var matchesConverterNode = downloadRegexInputNode.AddChild(regexConverter, "GetMatches", 0).EndPoint;
            matchesConverterNode.Description = "matches";
            pageDownloaderConverterNode.AddChild(matchesConverterNode, 1);

            var matchValueConverterNode = matchesConverterNode.AddChild(regexConverter, "GetValue", 0).EndPoint;
            matchValueConverterNode.Description = "matchValue";

            var zipAddressNode = baseUriInputNode.AddChild(webAddressConverter, "FromStringWithBaseUri", 0).EndPoint;
            matchValueConverterNode.AddChild(zipAddressNode, 1);

            var zipDownloaderConverterNode = zipAddressNode.AddChild(downloader, "GetBytes", 0).EndPoint;
            zipDownloaderConverterNode.Description = "zipDownloader";

            var zipFileConverterNode = zipDownloaderConverterNode.AddChild(zipFileConverter, "Read", 0).EndPoint;
            zipFileConverterNode.Description = "zipFile";

            var zipEntriesConverterNode = zipFileConverterNode.AddChild(zipFileConverter, "GetEntries", 0).EndPoint;
            zipEntriesConverterNode.Description = "zipEntries";
            filterRegexInputNode.AddChild(zipEntriesConverterNode, 1);

            //////////////////
            // Add outputs: //
            //////////////////
            var entryOutputter = zipEntriesConverterNode.AddChild(zipEntryOutputter, "Extract", 0).EndPoint;
            entryOutputter.Description = "entry";
            outputDirectoryInputNode.AddChild(entryOutputter, 1);

            Assert.IsTrue(TemplateValidator.IsComplete(template));
            Assert.AreEqual(13, TemplateDepthCalculator.GetDepth(template));
            Assert.AreEqual(12, TemplateDepthCalculator.GetDepth(zipEntriesConverterNode));
            Assert.AreEqual(2, TemplateDepthCalculator.GetDepth(pagesRangeConverterNode));

            var graph = TemplateDepthCalculator.GetGraph(template);

            //SimpleExecutor.Run(template);
        }
    }
}